package main.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

import main.KeysExecution;
import main.KeysVal;

/**
 * Initial (GUI)
 * -------------------------------------
 * 
 * - This class represents the vision of the program.
 * - Its extend of JFrame and use Swing 
 * 
 * @author caio thomas
 */
public class Initial3 extends JFrame  implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	
	public JMenu file;		
	public JMenuItem openXML;        
	public JMenuItem exit;
	public JMenu help;
	public JMenuItem menuAbout;
	public JMenuBar menubar;
    
	private JTextArea t1;
	private JTextArea t3Result;
	private JTextArea t4Error;
	private JScrollPane t1Sp;
	private JPanel t1p;
	private JPanel panelSouth;
	private JPanel panelResult;
	private JPanel panelError;
	private String filename = new String();
	private String fileUpd = new String();
	private KeysVal kv = new KeysVal();
	private JOptionPane jp = new JOptionPane(); // for indicade the size of file ultrapasse the textarea
	
	public static KeysExecution ke = new KeysExecution();
	public static String ErrorMessage = new String("");
	public static FileWriter fw;
	public static JTextArea t2;
	public static JButton kTree;
	
	private JButton keysF;		
	private JButton openF;
	private JButton updtF;			
	private JButton incvF;	
	
	public File f = null;
	public JFileChooser fileChooser = new JFileChooser();
	public static Initial3 app = null;
	private static DialogXDF dialogXDF = null;
	
	public Initial3()
	{
		super("XDF Validation");
		
		t1 = new JTextArea(10, 15);
		t2 =  new JTextArea(10, 15);		
		t3Result = new JTextArea(10, 15);
		t4Error = new JTextArea(10, 15);
		t1p = new JPanel();
		t1Sp = new JScrollPane(t1);
		panelSouth = new JPanel();
		panelResult = new JPanel();
		panelError = new JPanel();
		
		//menu
		file = new JMenu("File");
		openXML = new JMenuItem("Open File...");
		help = new JMenu("Help");
		menuAbout = new JMenuItem("About");
		menubar = new JMenuBar();
        exit = new JMenuItem("Exit");		
		
        exit.addActionListener(this);
        openXML.addActionListener(this);
        help.addActionListener(this);
        
        file.add(openXML);
        file.add(new JSeparator());        
        file.add(exit);
        
        help.add(menuAbout);

        menubar.add(file);		
        menubar.add(help);
        menubar.add(file);		
        menubar.add(help);
        menubar.add(file);		
        menubar.add(help);        

        //left sidebar menu
        kTree =  new JButton("Validation");        
        keysF = new JButton("Enter XML-XDF");
		openF = new JButton("Open XML File");
		updtF = new JButton("Update List");
		incvF = new JButton("Update Validation");
				       
		JPanel panelPrincipal = new JPanel(); 
		panelPrincipal.setLayout(new GridLayout(2,1,0,0));
				
		t1.setEditable(false);	
		t2.setEditable(false);
		t3Result.setEditable(false);	
		t4Error.setEditable(false);
					
		
		//box xml document and automatos
		t1p.setBorder(BorderFactory.createTitledBorder("XML Document / Constraints"));
		t1p.add(t1Sp);
		t1p.setLayout(new GridLayout(1,2)); 
		t1p.add(new JScrollPane(t2));		
				 
		panelSouth.setLayout(new GridLayout(1,2));
		
		panelResult.setBorder(BorderFactory.createTitledBorder("Validation Results:"));		
		panelResult.setLayout(new GridLayout(1,1)); 
		panelResult.add(new JScrollPane(t3Result));
		
		panelError.setBorder(BorderFactory.createTitledBorder("Error Validation:"));
		panelError.setLayout(new GridLayout(1,1)); 
		panelError.add(new JScrollPane(t4Error));		
        t4Error.setForeground(Color.RED);
        
		panelSouth.add(panelResult);
		panelSouth.add(panelError);
		
		//create new menu sidebar left
    	Panel t3p = new Panel();
    	Box b = Box.createVerticalBox();
    	
    	ArrayList<JButton> botoes = new ArrayList<JButton>();        
		botoes.add(openF);
		botoes.add(keysF);
		botoes.add(kTree);
		botoes.add(updtF);
		botoes.add(incvF);

        for (JButton botao : botoes){
            botao.addActionListener(this);
            botao.setPreferredSize(new Dimension(150,30));
            botao.setMaximumSize(new Dimension(150,30));
            botao.setEnabled(false);            
            b.add(botao);    		           
        }        	
		
        openF.setEnabled(true);
        t3p.add(b);
		
		Panel panelMediun = new Panel();
		panelMediun.setLayout(new BorderLayout());
		panelMediun.add(t3p,BorderLayout.WEST);
		panelMediun.add(t1p,BorderLayout.CENTER);
		panelPrincipal.add(panelMediun);		
		panelPrincipal.add(panelSouth);					
		
		this.add(panelPrincipal);
		this.setJMenuBar(menubar);
		this.setSize(800, 400);
		this.setVisible(true);	
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	/**
	 * This function its a JFileChoser
	 * @return the file select, its a string
	 */
	private String selectFile()
	{
		String name = new String();
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		
		int result = fileChooser.showOpenDialog(this);
		
		if (result == JFileChooser.CANCEL_OPTION)
			return "error";
		
		File fname = fileChooser.getSelectedFile();
		
		if (fname == null || fname.getName().equals(""))
			JOptionPane.showMessageDialog(this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE);
		else 
			name = "" + fname;		
		
		return name;
	}
	
	
	private String selectFile2()
	{		
		String name = new String();
		
		fileChooser.setDialogTitle("Select a xml file");
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		filterFile(fileChooser);
		String s = System.getProperty("user.dir");
		File f1 = new File (s);
		fileChooser.setCurrentDirectory(f1);
		
		//Save the last path selected to oppen the chooser in there
		if (f != null )
		{
			String path = fileChooser.getSelectedFile().getAbsolutePath();
			String lastPath;
			
			if(!LookAndFeel.isUnix())
				lastPath = path.substring(0, path.lastIndexOf("\\"));
			else
				lastPath = path.substring(0, path.lastIndexOf("/"));
			
			f = new File(lastPath);
			fileChooser.setCurrentDirectory(f);
			path = "" + f;
		}
		
		int result = fileChooser.showDialog(fileChooser.getParent(), null) ;

		if (result == JFileChooser.CANCEL_OPTION)
			return "error";
		else
		{
			name = fileChooser.getSelectedFile().getAbsolutePath() ;
			f = new File (name);
			return name;
		}
	}
	
	/**
	 * Lets just xml files are selected by the JFileChooser
	 */
	public void filterFile(JFileChooser j)
	{			
		j.setFileFilter(new javax.swing.filechooser.FileFilter()
		{
			public boolean accept (File f)
			{
				return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
			}
			
			//Text show to user
			public String getDescription()
			{
				return "Only files xml (.xml)";
			}
			
		});
	}		


	
	
	/**
	 * This function read the file xml
	 * @param fname string
	 * @return string of file or error
	 */
	private String openFile(String fname)
	{
		String xml = new String();
		try
		{
			FileInputStream in = new FileInputStream(fname);
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String s = br.readLine();
			while (s != null)
			{
				xml = xml + s + "\n";
				s = br.readLine();
			}
			
			return (xml);			
		}
		catch (Exception e)
		{
			System.out.println(e);
			xml = "error: corrupted file";
			return (xml);
		}
	}

	/**
	 * This function call the Initial Frame
	 * @param args
	 * @return void
	 */
	public static void main(String[] args)
	{
		LookAndFeel.initLookAndFeel();
		Initial3.app = new Initial3();
	}	
	
	public static DialogXDF singleDialogXDF()
	{
		if(dialogXDF == null)
			dialogXDF = new DialogXDF();
		else
			dialogXDF.clean();
		return dialogXDF;
	}	
	
	@Override
	public void actionPerformed(ActionEvent e) {		
        Object origem = e.getSource();		
        
        if(origem == exit)
        	System.exit(0);
        else if(origem == kTree){
			try{																
				t3Result.setText(kv.parseKeysVal(filename, ke) + "\n"+ kv.getResult());
				t4Error.setText(kv.getErrosConstraint());
			}
			catch (Exception ex){
                JOptionPane.showMessageDialog(this,"Error KTree:" + ex.getMessage(), "Attention", JOptionPane.ERROR_MESSAGE);                                                                        				
				System.err.println("Error KTree:" + ex.getMessage());
			}		
		}   
        else if(origem == updtF)
		{
			t1p.setBorder(BorderFactory.createTitledBorder("XInitial app = ML Document / Update Operations List"));  
			fileUpd = selectFile();
			t2.setText(openFile(fileUpd));    	   
   		}
		else if(origem == keysF)
			singleDialogXDF().setVisible(true);						
		else if(origem == openF || origem == openXML)
		{
			//filename = selectFile();
			int size = 999000000;
			filename = selectFile2();
			System.out.println("Nome do arquivo: "+ filename);
			
			if(!filename.equals("error"))
			{
				File f = new File (filename);
				if (f.length() < size) // Tests the file size if it is larger than 50MB will not be displayed
				{							
					    //t1.setText(openFile(filename));
						Tree t = new Tree();
						long tempoInicial = System.currentTimeMillis(); 
					    t1Sp.setViewportView(t.createTree(filename));
					    long tempoFinal = System.currentTimeMillis();
						System.out.println("Tempo de criacaoo da arvore: "+((tempoFinal - tempoInicial)/60000000) +" minutos");						
						repaint();
				}
				else
				{
					JOptionPane.showMessageDialog(null, "The file  " + filename + "\n is larger than " + size+" bytes, will not be displayed.");
					t1.setText("The file: \n"+ filename+ "\n" + " is very big to be displayed.");
				}
			
				keysF.setEnabled(true);		
			}
		}
	}	
}
